import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.util.HashSet;
import java.util.Set;
import org.rsbot.event.events.MessageEvent;
import org.rsbot.event.listeners.MessageListener;
import org.rsbot.event.listeners.PaintListener;
import org.rsbot.script.Script;
import org.rsbot.script.ScriptManifest;
import org.rsbot.script.methods.Calculations;
import org.rsbot.script.methods.Camera;
import org.rsbot.script.methods.Environment;
import org.rsbot.script.methods.Game;
import org.rsbot.script.methods.Interfaces;
import org.rsbot.script.methods.Inventory;
import org.rsbot.script.methods.Mouse;
import org.rsbot.script.methods.Skills;
import org.rsbot.script.methods.Walking;
import org.rsbot.script.util.Timer;
import org.rsbot.script.wrappers.RSArea;
import org.rsbot.script.wrappers.RSComponent;
import org.rsbot.script.wrappers.RSInterface;
import org.rsbot.script.wrappers.RSModel;
import org.rsbot.script.wrappers.RSObject;
import org.rsbot.script.wrappers.RSPlayer;
import org.rsbot.script.wrappers.RSTile;
import org.rsbot.script.wrappers.RSTilePath;

@ScriptManifest(authors={"Aion"}, name="Aion's Air Crafter", version=0.2D, description="Either wear an air tiara or have an air talisman in your inventory.")
public class AionAirCrafter extends Script
  implements PaintListener, MessageListener
{
  private int runesCrafted;
  private int startExp;
  private int startLvl;
  private Set<AionAirCrafter.Action> actions;
  private AionAirCrafter.Action action;
  private Timer timer;

  public boolean onStart()
  {
    this.timer = new Timer(0L);

    this.actions = new HashSet();

    this.actions.add(new AionAirCrafter.BankAction(this));

    this.actions.add(new AionAirCrafter.1(this, "Enter", 2452));

    this.actions.add(new AionAirCrafter.2(this, "Craft-rune", 2478));

    this.actions.add(new AionAirCrafter.3(this, "Enter", 2465));

    this.actions.add(new AionAirCrafter.4(this, this.walking.newTilePath(AionAirCrafter.Constants.PATH).reverse()));

    this.actions.add(new AionAirCrafter.5(this, this.walking.newTilePath(AionAirCrafter.Constants.PATH)));

    this.startExp = this.skills.getCurrentExp(20);
    this.startLvl = this.skills.getCurrentLevel(20);
    return true;
  }

  public int loop() {
    if (this.interfaces.get(741).isValid()) {
      this.interfaces.getComponent(741, 9).doClick();
      return random(300, 500);
    }if (this.interfaces.get(740).isValid()) {
      this.env.saveScreenshot(false);
      this.interfaces.getComponent(740, 3).doClick();
      sleep(600, 700);
      if (this.game.getCurrentTab() != 2) {
        this.game.openTab(2);
        sleep(800, 1200);
      }
      this.skills.doHover(104);
      sleep(150, 300);
      this.mouse.click(true);
      return random(random(1000, 1300), 2000);
    }

    if (this.action != null) {
      if (this.action.isValid())
        this.action.process();
      else
        this.action = null;
    }
    else {
      for (AionAirCrafter.Action localAction : this.actions) {
        if (localAction.isValid()) {
          this.action = localAction;
          break;
        }
      }
    }
    if (random(1, 10) == random(1, 6)) {
      antiban();
    }
    return random(200, 400);
  }

  public void onRepaint(Graphics paramGraphics) {
    if ((this.game.isLoggedIn()) && (!this.game.isLoginScreen())) {
      paramGraphics.setColor(new Color(16, 16, 16, 123));
      paramGraphics.fillRoundRect(8, 179, 243, 153, 15, 15);

      paramGraphics.setColor(Color.RED);
      paramGraphics.draw3DRect(13, 291, 231, 15, true);

      paramGraphics.setColor(new Color(48, 225, 48, 170));
      paramGraphics.fill3DRect(14, 292, getPercentToLvl() * 229 / 100, 14, true);

      paramGraphics.setColor(Color.WHITE);
      paramGraphics.drawString("Aion's Air Crafter v" + getVersion(), 65, 192);
      paramGraphics.drawString("Runtime: " + getRuntime(), 13, 206);

      paramGraphics.drawString("Crafted " + format(getRunesCrafted()) + " air runes", 13, 225);
      paramGraphics.drawString("Gained " + format(getExpGained()) + " exp", 13, 239);
      paramGraphics.drawString("Runes/Hour: " + format((int)getRunesHour()), 140, 225);
      paramGraphics.drawString("Exp/Hour: " + format((int)getExpHour()), 140, 239);

      int i = getLvlGained();
      localObject = i == 0 ? "runecrafting" : "";
      paramGraphics.drawString("Current " + (String)localObject + " level: " + getRunecraftLvl(), 13, 258);
      if (i != 0) {
        localObject = i == 1 ? "" : "s";
        paramGraphics.drawString("Gained " + i + " level" + (String)localObject, 140, 258);
      }

      paramGraphics.drawString("Exp left: " + format(getExpToLvl()), 13, 272);
      paramGraphics.drawString("Runes left: " + format(getRunesLeft()), 140, 272);
      paramGraphics.drawString("Estimated time to level: " + getTimeToLvl(), 13, 286);
      paramGraphics.drawString(getPercentToLvl() + "%", 113, 303);

      if (this.action != null) {
        paramGraphics.drawString("Status: " + this.action.getDesc(), 13, 325);
      }

    }

    Point localPoint = this.mouse.getLocation();
    Object localObject = this.mouse.getPressLocation();
    long l = System.currentTimeMillis() - this.mouse.getPressTime();

    if (l < 1000L) {
      paramGraphics.setColor(Color.red);
      paramGraphics.drawOval(((Point)localObject).x - 2, ((Point)localObject).y - 2, 4, 4);
      paramGraphics.drawOval(((Point)localObject).x - 9, ((Point)localObject).y - 9, 18, 18);
    }

    paramGraphics.setColor(Color.YELLOW);
    paramGraphics.drawOval(localPoint.x - 2, localPoint.y - 2, 4, 4);
    paramGraphics.drawOval(localPoint.x - 9, localPoint.y - 9, 18, 18);
  }

  public void messageReceived(MessageEvent paramMessageEvent) {
    String str = paramMessageEvent.getMessage().toLowerCase();
    if (str.contains("bind the temple"))
      this.runesCrafted += this.inventory.getCount(new int[] { 1436 });
    else if (str.contains("you've just"))
      log(str);
  }

  private void antiban()
  {
    switch (random(1, 50)) {
    case 2:
      if (random(1, 5) != 1) {
        break;
      }
      this.mouse.moveSlightly();
      break;
    case 6:
      if (random(1, 18) != 7) {
        break;
      }
      if (this.game.getCurrentTab() != 2) {
        this.game.openTab(2);
        sleep(500, 900);
      }
      this.skills.doHover(104);
      sleep(random(1400, 2000), 3000);
      if (random(0, 5) != 3) {
        break;
      }
      this.mouse.moveSlightly();
      break;
    case 9:
    case 14:
    case 17:
    case 25:
      this.camera.setAngle(random(-360, 360));
      break;
    case 30:
    case 34:
    case 37:
    case 40:
      this.camera.setPitch(this.camera.getPitch() >= random(65, 101) ? random(0, 61) : random(61, 101));
    case 3:
    case 4:
    case 5:
    case 7:
    case 8:
    case 10:
    case 11:
    case 12:
    case 13:
    case 15:
    case 16:
    case 18:
    case 19:
    case 20:
    case 21:
    case 22:
    case 23:
    case 24:
    case 26:
    case 27:
    case 28:
    case 29:
    case 31:
    case 32:
    case 33:
    case 35:
    case 36:
    case 38:
    case 39: }  } 
  private boolean canCraft() { return this.inventory.contains(1436); }

  private String format(int paramInt)
  {
    return format(String.valueOf(paramInt));
  }

  private String format(String paramString) {
    if (paramString.length() < 4) {
      return paramString;
    }
    return format(paramString.substring(0, paramString.length() - 3)) + "," + paramString.substring(paramString.length() - 3, paramString.length());
  }

  private int getExpGained()
  {
    if ((this.startExp == -1) && 
      (this.game.getClientState() == 10)) {
      this.startExp = this.skills.getCurrentExp(20);
    }

    return this.skills.getCurrentExp(20) - this.startExp;
  }

  private double getExpHour() {
    int i = getExpGained();
    long l = System.currentTimeMillis() - this.timer.getElapsed();
    return i * 3600000.0D / (System.currentTimeMillis() - l);
  }

  private int getExpToLvl() {
    return this.skills.getExpToNextLevel(20);
  }

  private int getLvlGained() {
    if ((this.startLvl == -1) && 
      (this.game.getClientState() == 10)) {
      this.startLvl = this.skills.getCurrentLevel(20);
    }

    return this.skills.getCurrentLevel(20) - this.startLvl;
  }

  private int getPercentToLvl() {
    return this.skills.getPercentToNextLevel(20);
  }

  private int getRunecraftLvl() {
    return this.skills.getCurrentLevel(20);
  }

  private int getRunesCrafted() {
    return this.runesCrafted;
  }

  private double getRunesHour() {
    int i = getRunesCrafted();
    long l = System.currentTimeMillis() - this.timer.getElapsed();
    return i * 3600000.0D / (System.currentTimeMillis() - l);
  }

  private int getRunesLeft() {
    return getExpToLvl() / 5;
  }

  private String getRuntime() {
    return this.timer.toElapsedString();
  }

  private Point getScreenPoint(RSObject paramRSObject) {
    if (paramRSObject != null) {
      RSModel localRSModel = paramRSObject.getModel();
      if (localRSModel != null) {
        for (Polygon localPolygon : localRSModel.getTriangles()) {
          for (int k = 0; k < localPolygon.npoints; k++) {
            Point localPoint = new Point(localPolygon.xpoints[k], localPolygon.ypoints[k]);
            if (this.calc.pointOnScreen(localPoint)) {
              return localPoint;
            }
          }
        }
      }
    }
    return new Point(-1, -1);
  }

  private String getTimeFormat(long paramLong) {
    return Timer.format(paramLong);
  }

  private String getTimeToLvl() {
    return getTimeFormat(()(getExpToLvl() / getExpHour() * 3600000.0D));
  }

  private double getVersion() {
    return AionAirCrafter.Constants.VERSION;
  }

  private boolean inAltar() {
    return AionAirCrafter.Constants.AREA_ALTAR.contains(new RSTile[] { getMyPlayer().getLocation() });
  }

  private boolean inBank() {
    return AionAirCrafter.Constants.AREA_BANK.contains(new RSTile[] { getMyPlayer().getLocation() });
  }

  private boolean inRuins() {
    return AionAirCrafter.Constants.AREA_RUINS.contains(new RSTile[] { getMyPlayer().getLocation() });
  }

  private boolean inMusician() {
    return AionAirCrafter.Constants.AREA_MUSICIAN.contains(new RSTile[] { getMyPlayer().getLocation() });
  }

  private void waitForAnim(int paramInt) {
    long l = System.currentTimeMillis() + paramInt;
    while ((System.currentTimeMillis() < l) && 
      (getMyPlayer().getAnimation() == -1))
    {
      sleep(5, 15);
    }
  }

  private void waitForIface(int paramInt1, int paramInt2) {
    long l = System.currentTimeMillis() + paramInt2;
    while ((System.currentTimeMillis() < l) && 
      (!this.interfaces.get(paramInt1).isValid()))
    {
      sleep(5, 15);
    }
  }

  private boolean waitToMove(int paramInt) {
    long l = System.currentTimeMillis() + paramInt;
    while (System.currentTimeMillis() < l) {
      if (getMyPlayer().isMoving()) {
        return true;
      }
      sleep(5, 15);
    }
    return false;
  }

  private void waitToStop() {
    do
      sleep(5, 15);
    while (getMyPlayer().isMoving());
  }
}